home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
gdb
/
gdb_18s.zoo
/
fake
/
console.c
next >
Wrap
C/C++ Source or Header
|
1992-03-28
|
4KB
|
210 lines
/*
* console input/output routines.
* written by Eric R. Smith and placed in the public domain
*/
/*
* BUGS: assumes that all tty handles >= 0 are console handles.
* If we have some handles >= 0 not attached to the console,
* and some other handles attached to a different device, we might
* get characters mixed up. This will generally not be a problem,
* since earlier versions of the library forbid any non-console
* devices entirely.
*/
#include <osbind.h>
#include <support.h>
#include <stdlib.h>
#include <ioctl.h>
#include <tchars.h>
#include <signal.h>
#include <unistd.h>
#ifndef _COMPILER_H
#include <compiler.h>
#endif
extern int _console_dev; /* in main.c */
int __check_signals = 0;
#define KBUFSIZ 80
#define NUMDEV 3
/* 0 == prn:, 1 == aux:, 2 == con: */
typedef struct _buffer {
short head, tail;
long buffer[KBUFSIZ];
} k_buf;
k_buf in_buf[NUMDEV];
#define IN_BUF(dev) (&in_buf[(dev) > 2 ? _console_dev : (dev)])
/*
* what handle means:: 0-2: BIOS handle, 3: stdout, 4: stderr
*/
static short LOOKUP __PROTO((short handle));
static long raw_in __PROTO((int dev));
static long raw_instat __PROTO((int dev));
#if 0
static void raw_out __PROTO((int dev, int c));
#endif
static short
#ifdef __STDC__
LOOKUP(short handle)
#else
LOOKUP(handle)
short handle;
#endif
{
switch(handle) {
case -3:
case -2:
case -1:
case 0:
return handle + 3;
case 2:
return 4;
case 1:
if (isatty(0)) return 3;
if (isatty(2)) return 4;
/* else fall through */
default:
return _console_dev;
}
}
/*
* raw i/o routines
*/
static long
raw_in(dev)
int dev;
{
if (dev < 3)
return Bconin(dev);
else if (dev == 3)
return Crawcin();
else
return Cauxin();
}
#if 0
static void
raw_out(dev, c)
int dev, c;
{
if (dev < 3)
Bconout(dev, c);
else if (dev == 3)
(void)Crawio(c);
else
Cauxout(c);
}
#endif
static long
raw_instat(dev)
int dev;
{
if (dev < 3)
return Bconstat(dev);
else if (dev == 3)
return Cconis();
else
return Cauxis();
}
/*
* somewhat less raw i/o routines. The main difference is that these ones
* will check for pending input before doing output, to see if a signal
* needs to be raised. This is only done if __check_signals is non-zero;
* signal() should set __check_signals when the user attempts to catch
* SIGINT or SIGQUIT. We don't do this checking all the time because
* the user may be typing ahead input for another program (e.g. if this
* is a little utility of some sort) and we shouldn't steal keystrokes
* unless necessary.
*/
unsigned int console_read_byte(handle)
int handle;
{
k_buf *p;
short i, j, dev;
long r;
dev = LOOKUP(handle);
p = IN_BUF(dev);
if ( p->head != (i = p->tail)) {
j = p->tail + 1;
if (j >= KBUFSIZ)
j = 0;
p->tail = j;
r = p->buffer[i];
}
else
r = raw_in(dev);
return r;
}
int console_input_status(handle)
int handle;
{
short dev;
k_buf *p;
dev = LOOKUP(handle);
p = IN_BUF(dev);
return (p->head != p->tail) || raw_instat(dev);
}
void
console_write_byte(handle, n)
int handle;
int n;
{
long c;
short i, j, waiting = 0;
char ch;
k_buf *p;
short dev;
dev = LOOKUP(handle);
p = IN_BUF(dev);
while (__check_signals && (raw_instat(dev) || waiting)) {
c = raw_in(dev);
if (!(__ttymode & RAW)) {
ch = c & 0xff;
if (ch == ('S'-'@')) {
waiting = 1;
}
else if (ch == ('Q'-'@')) {
waiting = 0;
}
else if (ch == __tchars[TC_INTRC]) {
p->head = p->tail;
raise(SIGINT);
}
else if (ch == __tchars[TC_QUITC]) {
p->head = p->tail;
raise(SIGQUIT);
}
else if (!waiting) {
i = p->head;
j = i + 1;
if (j >= KBUFSIZ) j = 0;
if (j != p->tail) {
p->buffer[i] = c;
p->head = j;
}
}
}
}
/* raw_out(dev, n); */
ch = n;
(void)Fwrite(handle, 1L, &ch);
}